#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>

#include "debug.h"
#include "os_api.h"

#define _STACK_1_SIZE			0x2000
#define _STACK_2_SIZE			0x2000
static void* _task_1_stack = NULL;
static void* _task_2_stack = NULL;

static OSTaskRef _task_1_ref = NULL;
static OSTaskRef _task_2_ref = NULL;

static OSMutexRef testMuteRef = NULL;

void testMutexInit(void);
void testMutexLock(void);
void testMutexUnlock(void);

static char dataBuffer[1024] = {0};
static int dataBufferLen = 0;

int test_write_to_buffer(char* buffer, int len)
{
	int i;
	int writeLen = 0;

	testMutexLock();
	if ((dataBufferLen + len) > 1024){
		LOG_PRINTF("Buffer overflow!\n");
		writeLen = 0;
	}else{
		writeLen = len;
	}
	
	for(i = 0; i < writeLen ; i++){
		dataBuffer[dataBufferLen++] = buffer[i];
	}	
	testMutexUnlock();

	return writeLen;	
}

int test_read_from_buffer(char* buffer, int len)
{
	int i;
	int readLen = 0;

	testMutexLock();
	readLen = (len >= dataBufferLen) ? dataBufferLen : len;			

	for(i = 0; i < readLen ; i++){
		buffer[i] = dataBuffer[i];
	}	
	
	dataBufferLen = dataBufferLen - readLen;

	if (dataBufferLen > 0){
		for(i = 0; i < dataBufferLen ; i++){
			dataBuffer[i] = dataBuffer[readLen + i];
		}
	}
	testMutexUnlock();

	return readLen;
}

static void _task_1(void *ptr)
{
	int ret;

	char testBuffer[128] = {0};
	while(1){
		memset(testBuffer, 0x41, sizeof(testBuffer));
		ret = test_write_to_buffer(testBuffer, 128);
		LOG_PRINTF("test_write_to_buffer ret %d!\n", ret);
		OSATaskSleep(50);		// 如果可能存在while空跑的case，一定需要加上个sleep，不然可能会造成系统调度异常
	}
}

static void _task_2(void *ptr)
{
	int ret;
	char testBuffer[256] = {0};

	while(1){
		memset(testBuffer, 0x00, sizeof(testBuffer));
		ret = test_read_from_buffer(testBuffer, 256);
		LOG_PRINTF("test_read_from_buffer ret %d, %s!\n", ret, testBuffer);
		OSATaskSleep(50);		// 如果可能存在while空跑的case，一定需要加上个sleep，不然可能会造成系统调度异常
	}
}

void testMutexInit(void)
{
    OSA_STATUS status;
	status = OSAMutexCreate(&testMuteRef, OS_PRIORITY);
	ASSERT(status == OS_SUCCESS);
}

void testMutexLock(void)
{
    OSA_STATUS status;
    status = OSAMutexLock(testMuteRef, OSA_SUSPEND);
    ASSERT(status == OS_SUCCESS);
}

void testMutexUnlock(void)
{
    OSA_STATUS status;
    status = OSAMutexUnlock(testMuteRef);
    ASSERT(status == OS_SUCCESS);
}


int main(void)
{	
    OSA_STATUS status;

	_task_1_stack = malloc(_STACK_1_SIZE);
    ASSERT(_task_1_stack != NULL);
	_task_2_stack = malloc(_STACK_2_SIZE);
    ASSERT(_task_2_stack != NULL);
	
	testMutexInit();

    status = OSATaskCreate(&_task_1_ref, _task_1_stack, _STACK_1_SIZE, 100, "_task_1", _task_1, NULL);
    ASSERT(status == OS_SUCCESS);
	
    status = OSATaskCreate(&_task_2_ref, _task_2_stack, _STACK_2_SIZE, 101, "_task_2", _task_2, NULL);
    ASSERT(status == OS_SUCCESS);	

	return 0;
}